<!DOCTYPE html>

<html>
<head>
  <title>camera.coffee</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page">
            
              
              <a class="source" href="analyze.html">
                analyze.coffee
              </a>
            
              
              <a class="source" href="autoload.html">
                autoload.coffee
              </a>
            
              
              <a class="source" href="blender.html">
                blender.coffee
              </a>
            
              
              <a class="source" href="calculate.html">
                calculate.coffee
              </a>
            
              
              <a class="source" href="caman.html">
                caman.coffee
              </a>
            
              
              <a class="source" href="convert.html">
                convert.coffee
              </a>
            
              
              <a class="source" href="event.html">
                event.coffee
              </a>
            
              
              <a class="source" href="filter.html">
                filter.coffee
              </a>
            
              
              <a class="source" href="io.html">
                io.coffee
              </a>
            
              
              <a class="source" href="layer.html">
                layer.coffee
              </a>
            
              
              <a class="source" href="logger.html">
                logger.coffee
              </a>
            
              
              <a class="source" href="module.html">
                module.coffee
              </a>
            
              
              <a class="source" href="pixel.html">
                pixel.coffee
              </a>
            
              
              <a class="source" href="plugin.html">
                plugin.coffee
              </a>
            
              
              <a class="source" href="renderer.html">
                renderer.coffee
              </a>
            
              
              <a class="source" href="store.html">
                store.coffee
              </a>
            
              
              <a class="source" href="util.html">
                util.coffee
              </a>
            
              
              <a class="source" href="blenders.html">
                blenders.coffee
              </a>
            
              
              <a class="source" href="filters.html">
                filters.coffee
              </a>
            
              
              <a class="source" href="size.html">
                size.coffee
              </a>
            
              
              <a class="source" href="blur.html">
                blur.coffee
              </a>
            
              
              <a class="source" href="camera.html">
                camera.coffee
              </a>
            
              
              <a class="source" href="compoundBlur.html">
                compoundBlur.coffee
              </a>
            
              
              <a class="source" href="edges.html">
                edges.coffee
              </a>
            
              
              <a class="source" href="posterize.html">
                posterize.coffee
              </a>
            
              
              <a class="source" href="presets.html">
                presets.coffee
              </a>
            
              
              <a class="source" href="rotate.html">
                rotate.coffee
              </a>
            
              
              <a class="source" href="stackBlur.html">
                stackBlur.coffee
              </a>
            
              
              <a class="source" href="threshold.html">
                threshold.coffee
              </a>
            
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>camera.coffee</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              
            </div>
            
            <div class="content"><div class='highlight'><pre>vignetteFilters =
  brightness: (rgba, amt, opts) -&gt;
    rgba.r = rgba.r - (rgba.r * amt * opts.strength)
    rgba.g = rgba.g - (rgba.g * amt * opts.strength)
    rgba.b = rgba.b - (rgba.b * amt * opts.strength)
    rgba
    
  gamma: (rgba, amt, opts) -&gt;
    rgba.r = Math.pow(rgba.r / <span class="number">255</span>, Math.max(<span class="number">10</span> * amt * opts.strength, <span class="number">1</span>)) * <span class="number">255</span>
    rgba.g = Math.pow(rgba.g / <span class="number">255</span>, Math.max(<span class="number">10</span> * amt * opts.strength, <span class="number">1</span>)) * <span class="number">255</span>
    rgba.b = Math.pow(rgba.b / <span class="number">255</span>, Math.max(<span class="number">10</span> * amt * opts.strength, <span class="number">1</span>)) * <span class="number">255</span>
    rgba
    
  colorize: (rgba, amt, opts) -&gt;
    rgba.r -= (rgba.r - opts.color.r) * amt;
    rgba.g -= (rgba.g - opts.color.g) * amt;
    rgba.b -= (rgba.b - opts.color.b) * amt;
    rgba

Filter.register <span class="string">"vignette"</span>, (size, strength = <span class="number">60</span>) -&gt;
  <span class="keyword">if</span> <span class="keyword">typeof</span> size <span class="keyword">is</span> <span class="string">"string"</span> <span class="keyword">and</span> size.substr(-<span class="number">1</span>) <span class="keyword">is</span> <span class="string">"%"</span>
    <span class="keyword">if</span> <span class="property">@dimensions</span>.height &gt; <span class="property">@dimensions</span>.width
      size = <span class="property">@dimensions</span>.width * (parseInt(size.substr(<span class="number">0</span>, size.length - <span class="number">1</span>), <span class="number">10</span>) / <span class="number">100</span>)
    <span class="keyword">else</span>
      size = <span class="property">@dimensions</span>.height * (parseInt(size.substr(<span class="number">0</span>, size.length - <span class="number">1</span>), <span class="number">10</span>) / <span class="number">100</span>)

  strength /= <span class="number">100</span>
  center = [<span class="property">@dimensions</span>.width / <span class="number">2</span>, <span class="property">@dimensions</span>.height / <span class="number">2</span>]
  start = Math.sqrt Math.pow(center[<span class="number">0</span>], <span class="number">2</span>) + Math.pow(center[<span class="number">1</span>], <span class="number">2</span>)
  end = start - size
  bezier = Calculate.bezier [<span class="number">0</span>, <span class="number">1</span>], [<span class="number">30</span>, <span class="number">30</span>], [<span class="number">70</span>, <span class="number">60</span>], [<span class="number">100</span>, <span class="number">80</span>]

  <span class="property">@process</span> <span class="string">"vignette"</span>, (rgba) -&gt;
    loc = rgba.locationXY()
    dist = Calculate.distance loc.x, loc.y, center[<span class="number">0</span>], center[<span class="number">1</span>]

    <span class="keyword">if</span> dist &gt; end
      div = Math.max <span class="number">1</span>, ((bezier[Math.round(((dist - end) / size) * <span class="number">100</span>)]/<span class="number">10</span>) * strength)

      rgba.r = Math.pow(rgba.r / <span class="number">255</span>, div) * <span class="number">255</span>
      rgba.g = Math.pow(rgba.g / <span class="number">255</span>, div) * <span class="number">255</span>
      rgba.b = Math.pow(rgba.b / <span class="number">255</span>, div) * <span class="number">255</span>

    rgba

Filter.register <span class="string">"rectangularVignette"</span>, (opts) -&gt;
  defaults =
    strength: <span class="number">50</span>
    cornerRadius: <span class="number">0</span>
    method: <span class="string">'brightness'</span>
    color:
      r: <span class="number">0</span>
      g: <span class="number">0</span>
      b: <span class="number">0</span>

  opts = Util.extend defaults, opts

  <span class="keyword">if</span> <span class="keyword">not</span> opts.size
    <span class="keyword">return</span> @
  <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">typeof</span> opts.size <span class="keyword">is</span> <span class="string">"string"</span>
    percent = parseInt(opts.size, <span class="number">10</span>) / <span class="number">100</span>
    opts.size =
      width: <span class="property">@dimensions</span>.width * percent
      height: <span class="property">@dimensions</span>.height * percent
  <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">typeof</span> opts.size <span class="keyword">is</span> <span class="string">"object"</span>
    <span class="keyword">for</span> dim <span class="keyword">in</span> [<span class="string">"width"</span>, <span class="string">"height"</span>]
      <span class="keyword">if</span> <span class="keyword">typeof</span> opts.size[dim] <span class="keyword">is</span> <span class="string">"string"</span>
        opts.size[dim] = <span class="property">@dimensions</span>[dim] * (parseInt(opts.size[dim], <span class="number">10</span>) / <span class="number">100</span>)
  <span class="keyword">else</span> <span class="keyword">if</span> opts.size <span class="keyword">is</span> <span class="string">"number"</span>
    size = opts.size
    opts.size =
      width: size
      height: size

  <span class="keyword">if</span> <span class="keyword">typeof</span> opts.cornerRadius <span class="keyword">is</span> <span class="string">"string"</span>
    opts.cornerRadius = (opts.size.width / <span class="number">2</span>) * (parseInt(opts.cornerRadius, <span class="number">10</span>) / <span class="number">100</span>)

  opts.strength /= <span class="number">100</span></pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Since pixels are discreet, force size to be an int</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  opts.size.width = Math.floor opts.size.width
  opts.size.height = Math.floor opts.size.height
  opts.image =
    width: <span class="property">@dimensions</span>.width
    height: <span class="property">@dimensions</span>.height

  <span class="keyword">if</span> opts.method <span class="keyword">is</span> <span class="string">"colorize"</span> <span class="keyword">and</span> <span class="keyword">typeof</span> opts.color <span class="keyword">is</span> <span class="string">"string"</span>
    opts.color = Convert.hexToRGB opts.color

  opts.coords =
    left: (<span class="property">@dimensions</span>.width - opts.size.width) / <span class="number">2</span>
    right: <span class="property">@dimensions</span>.width - opts.coords.left
    bottom: (<span class="property">@dimensions</span>.height - opts.size.height) / <span class="number">2</span>
    top: <span class="property">@dimensions</span>.height - opts.coords.bottom

  opts.corners = [
    {x: opts.coords.left + opts.cornerRadius, y: opts.coords.top - opts.cornerRadius},
    {x: opts.coords.right - opts.cornerRadius, y: opts.coords.top - opts.cornerRadius},
    {x: opts.coords.right - opts.cornerRadius, y: opts.coords.bottom + opts.cornerRadius},
    {x: opts.coords.left + opts.cornerRadius, y: opts.coords.bottom + opts.cornerRadius}
  ]

  opts.maxDist = Calculate.distance(<span class="number">0</span>, <span class="number">0</span>, opts.corners[<span class="number">3</span>].x, opts.corners[<span class="number">3</span>].y) - opts.cornerRadius

  <span class="property">@process</span> <span class="string">"rectangularVignette"</span>, (rgba) -&gt;
    loc = rgba.locationXY()</pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Trivial rejects</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="keyword">if</span> (loc.x &gt; opts.corners[<span class="number">0</span>].x <span class="keyword">and</span> loc.x &lt; opts.corners[<span class="number">1</span>].x) <span class="keyword">and</span> (loc.y &gt; opts.coords.bottom <span class="keyword">and</span> loc.y &lt; opts.coords.top)
      <span class="keyword">return</span> rgba
    <span class="keyword">if</span> (loc.x &gt; opts.coords.left &amp;&amp; loc.x &lt; opts.coords.right) &amp;&amp; (loc.y &gt; opts.corners[<span class="number">3</span>].y &amp;&amp; loc.y &lt; opts.corners[<span class="number">2</span>].y)
      <span class="keyword">return</span> rgba</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Need to figure out which section we&#39;re in. First, the easy ones, then the harder ones.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="keyword">if</span> loc.x &gt; opts.corners[<span class="number">0</span>].x &amp;&amp; loc.x &lt; opts.corners[<span class="number">1</span>].x &amp;&amp; loc.y &gt; opts.coords.top</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>top-middle section</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      amt = (loc.y - opts.coords.top) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.y &gt; opts.corners[<span class="number">2</span>].y &amp;&amp; loc.y &lt; opts.corners[<span class="number">1</span>].y &amp;&amp; loc.x &gt; opts.coords.right</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>right-middle section</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      amt = (loc.x - opts.coords.right) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.x &gt; opts.corners[<span class="number">0</span>].x &amp;&amp; loc.x &lt; opts.corners[<span class="number">1</span>].x &amp;&amp; loc.y &lt; opts.coords.bottom</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>bottom-middle section</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      amt = (opts.coords.bottom - loc.y) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.y &gt; opts.corners[<span class="number">2</span>].y &amp;&amp; loc.y &lt; opts.corners[<span class="number">1</span>].y &amp;&amp; loc.x &lt; opts.coords.left</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>left-middle section</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      amt = (opts.coords.left - loc.x) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.x &lt;= opts.corners[<span class="number">0</span>].x &amp;&amp; loc.y &gt;= opts.corners[<span class="number">0</span>].y</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>top-left corner</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      radialDist = Caman.distance(loc.x, loc.y, opts.corners[<span class="number">0</span>].x, opts.corners[<span class="number">0</span>].y)
      amt = (radialDist - opts.cornerRadius) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.x &gt;= opts.corners[<span class="number">1</span>].x &amp;&amp; loc.y &gt;= opts.corners[<span class="number">1</span>].y</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>top-right corner</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      radialDist = Caman.distance(loc.x, loc.y, opts.corners[<span class="number">1</span>].x, opts.corners[<span class="number">1</span>].y)
      amt = (radialDist - opts.cornerRadius) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.x &gt;= opts.corners[<span class="number">2</span>].x &amp;&amp; loc.y &lt;= opts.corners[<span class="number">2</span>].y</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>bottom-right corner</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      radialDist = Caman.distance(loc.x, loc.y, opts.corners[<span class="number">2</span>].x, opts.corners[<span class="number">2</span>].y)
      amt = (radialDist - opts.cornerRadius) / opts.maxDist
    <span class="keyword">else</span> <span class="keyword">if</span> loc.x &lt;= opts.corners[<span class="number">3</span>].x &amp;&amp; loc.y &lt;= opts.corners[<span class="number">3</span>].y</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>bottom-left corner</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      radialDist = Caman.distance(loc.x, loc.y, opts.corners[<span class="number">3</span>].x, opts.corners[<span class="number">3</span>].y)
      amt = (radialDist - opts.cornerRadius) / opts.maxDist

    <span class="keyword">return</span> rgba <span class="keyword">if</span> amt &lt; <span class="number">0</span>
    <span class="keyword">return</span> vignetteFilters[opts.method](rgba, amt, opts)</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
